/**
 * Created with IntelliJ IDEA.
 * User: zzl
 * Date: 12-12-4
 * To change this template use File | Settings | File Templates.
 */
/**
 *
 *  click handlers should be added after applying repeatButton, otherwise it'll be fired on mouseup
 *
 */
(function ($, fnName, undefined) {

    var RepeatButton = function (button, options) {
        this.$button = $(button);
        this.options = options;
        this.setup();
    };

    var proto = { constructor: RepeatButton };
    RepeatButton.prototype = proto;

    proto.setup = function () {
        var me = this;

        me.$button.on('mousedown', function (e) {
            me.button_mousedown(e);
        });

        me.$button.on('mouseover', function (e) {
            me.button_mouseover(e);
        });

        me.$button.on('mouseout', function (e) {
            me.button_mouseout(e);
        });

        me.$button.on('click', function (e, clickCount) {
            if (clickCount === undefined) {
                e.stopImmediatePropagation();
            }
        });

        me.$button.on('dblclick', function(e) {
            if(jsex.msie && !me.$button.hasClass('disabled')) {
                me.$button.triggerHandler('click', [me.clickCounter++]);
            }
        });

        me.$button.on('keydown', function (e) {
            me.button_keydown(e);
        });

        me.$button.on('keyup', function (e) {
            me.button_keyup(e);
        });

        me.$button.on('blur', function (e) {
            me.button_blur(e);
        });

        //
        me.$button.on('mouseenter', function (e) {
            me.button_mouseenter(e);
        });

        me.$button.on('mouseleave', function (e) {
            me.button_mouseleave(e);
        });

    };

    proto.button_mouseenter = function (e) {
        var me = this;
        if (me.options.hoverInterval) {
            me.startHoverTimer();
        }
    };

    proto.button_mouseleave = function (e) {
        var me = this;
        me.stopHoverTimer();
    };

    proto.startHoverTimer = function (e) {
        var me = this;
        me.stopHoverTimer();
        var timerFunction = function () {
            if(!me.$button.hasClass('disabled')) {
                me.$button.triggerHandler('click', [me.clickCounter++]);
            }
            me.hoverTimer = setTimeout(timerFunction, me.options.hoverInterval);
        };
        timerFunction();
    };

    proto.stopHoverTimer = function () {
        var me = this;
        if (me.hoverTimer) {
            clearTimeout(me.hoverTimer);
            me.hoverTimer = null;
        }
    };

    proto.button_keydown = function (e) {
        var me = this;

        if (e.keyCode == 13) {
            return;
        }
        if (e.keyCode == 32 && !me.keyDowned) {
            me.keyDowned = true;
            me.startTimer();
        }
    };

    proto.button_keyup = function (e) {
        var me = this;
        if (me.keyDowned) {
            me.stopTimer();
            me.keyDowned = false;
        }
    };

    proto.button_blur = function (e) {
        var me = this;
        if (me.keyDowned) {
            me.stopTimer();
            me.keyDowned = false;
        }
    };

    proto.button_mousedown = function (e) {
        var me = this;
        me.downed = true;
        me.clickCounter = 0;
        me.startTimer();

        $(document).on('mouseup.' + fnName, function (e) {
            me.document_mouseup(e);
        });
//        e.preventDefault();
    };

    proto.document_mouseup = function (e) {
        var me = this;
        console.assert(me.downed);
        me.downed = false;
        me.stopTimer();
        $(document).off('mouseup.' + fnName);
    };

    proto.button_mouseover = function (e) {
        var me = this;
        if (!me.downed) {
            return;
        }
        me.startTimer();
    };

    proto.button_mouseout = function (e) {
        var me = this;
        if (!me.downed) {
            return;
        }
        me.stopTimer();
    };

    proto.startTimer = function () {
        var me = this;
        //
        me.stopHoverTimer();

        //
        var timerFunction = function (interval) {
            if(!me.$button.hasClass('disabled')) {
                me.$button.triggerHandler('click', [me.clickCounter++]);
            }
            me.timer = setTimeout(timerFunction, interval || me.options.interval);
        };
        timerFunction(me.options.delay);
    };

    proto.stopTimer = function () {
        var me = this;
        clearTimeout(me.timer);
    };

    $.fn.repeatButton = $.addPluginFn(fnName, RepeatButton, {
        delay: 250,
        interval: 60,
        hoverInterval: 0
    });

})(jQuery, 'repeatButton');